home *** CD-ROM | disk | FTP | other *** search
/ Almathera Ten Pack 3: CDPD 3 / Almathera Ten on Ten - Disc 3: CDPD3.iso / scope / 051-075 / scopedisk62 / filemap / file.c < prev    next >
C/C++ Source or Header  |  1995-03-19  |  4KB  |  203 lines

  1. /*  :ts=8 bk=0
  2.  * Filesystem routines (or, How To Find A File The Hard Way)
  3.  */
  4. #include <exec/types.h>
  5. #include <devices/trackdisk.h>
  6. #include "things.h"
  7.  
  8. extern struct IOExtTD    *diskreq;
  9. extern ULONG        diskchangecount, *diskbuffer;
  10.  
  11.  
  12. findfile (name)        /*  Traverse the filesystem the hard way  */
  13. char *name;
  14. {
  15.     register int err;
  16.     register char *b, *e;
  17.     char str[80];
  18.  
  19.     strcpy (str, name);
  20.     if (b = index (str, ':'))    /*  Ignore device names  */
  21.         b++;
  22.     else
  23.         b = str;
  24.  
  25.     while (*b == '/')    /*  Ignore leading slashes  */
  26.         b++;
  27.     if (!*b) {        /*  Don't do anything if string is empty  */
  28.         notice ("Badly formed filename.");
  29.         return (0);
  30.     }
  31.  
  32.     e = b;
  33.     MotorOn ();
  34.     GetSector (ROOTBLOCK);    /*  All paths are relative to the root  */
  35.     while (e) {
  36.         if (!*b) {
  37.             notice ("Badly formed filename.");
  38.             return (0);
  39.         }
  40.  
  41.         if (e = index (b, '/'))
  42.             *e = '\0';
  43.  
  44.         if ((err = traverse (b, hash (b))) < 0) {
  45.             switch (err) {
  46.             case -1:
  47.                 notice ("Badly formed path.");
  48.                 break;
  49.             case -2:
  50.                 notice ("File not found.");
  51.                 break;
  52.             }
  53.             return (0);
  54.         }
  55.  
  56.         if (e) {
  57. skip:            b = e+1;
  58.             while (*b == '/')
  59.                 b++;
  60.         }
  61.     }
  62.     drawfile ();
  63.     MotorOff ();
  64.     return (1);
  65. }
  66.  
  67. traverse (str, hash)    /*  Indirect through the disk blocks  */
  68. char *str;
  69. int hash;
  70. {
  71.     register int block;
  72.     register char *file = (char *) &diskbuffer [NAME];
  73.  
  74.     if (diskbuffer [TYPE] == T_SHORT &&
  75.         diskbuffer [SECONDARY_TYPE] == ST_FILE)
  76.         /*  Can't indirect out of a file  */
  77.         return (-1);
  78.  
  79.     strupper (str);
  80.     block = diskbuffer [hash];
  81.     for ever {
  82.         if (!block)
  83.             return (-2);    /*  No such file  */
  84.         GetSector ((long) block);
  85.         /*  Force null termination in case BCPL doesn't do it  */
  86.         file [*file + 1] = '\0';
  87.         strupper (file+1);    /*  Force to all upper case  */
  88.         if (!strcmp (str, file+1))    /*  Is this it?  */
  89.             break;
  90.         /*  This ain't it; traverse hash chain  */
  91.         block = diskbuffer [HASHCHAIN];
  92.     }
  93.     return (1);
  94. }
  95.  
  96. drawfile ()    /*  Draw file's allocated sectors  */
  97. {
  98.     register int i;
  99.  
  100.     /*
  101.      * File control blocks are marked with pen 1, data blocks with pen 2.
  102.      */
  103.     marksector (diskbuffer [HEADER_KEY], 1);
  104.  
  105.     if (diskbuffer [TYPE] == T_SHORT &&
  106.         diskbuffer [SECONDARY_TYPE] == ST_FILE)
  107.         for ever {
  108.             for (i=FH_BLOCKLIST; i>=FH_ENDLIST; i--)
  109.                 if (diskbuffer [i])
  110.                     marksector (diskbuffer [i], 2);
  111.             if (diskbuffer [EXTENSION]) {
  112.                 marksector (diskbuffer [EXTENSION], 1);
  113.                 GetSector (diskbuffer [EXTENSION]);
  114.             } else
  115.                 break;
  116.         }
  117. }
  118.  
  119. strupper (str)
  120. register char *str;
  121. {
  122.     while (*str) {
  123.         *str = toupper (*str);
  124.         str++;
  125.     }
  126. }
  127.  
  128.  
  129. /*
  130.  * The following routines were stolen from an RKM example by Bob Peck and
  131.  * hacked up a bit.
  132.  */
  133.  
  134. GetSector (sector)
  135. long sector;
  136. {
  137.     LONG offset = sector * BLOCKSIZE;
  138.  
  139.     diskreq -> iotd_Req.io_Length = BLOCKSIZE;      
  140.     diskreq -> iotd_Req.io_Data = (APTR) diskbuffer;    
  141.         /* show where to put the data when read */
  142.     diskreq -> iotd_Req.io_Command = ETD_READ;
  143.         /* check that disk not changed before reading */
  144.     diskreq -> iotd_Count = diskchangecount;
  145.     
  146.     /* convert from cylinder, head, sector to byte-offset value to get
  147.         * right one (as dos and everyone else sees it)...*/
  148.     
  149.     /* driver reads one CYLINDER at a time (head does not move for
  150.      * 22 sequential sector reads, or better-put, head doesnt move for
  151.      * 2 sequential full track reads.)
  152.      */
  153.     
  154.     diskreq -> iotd_Req.io_Offset = offset;
  155.     DoIO (diskreq);
  156.     return (0);
  157. }
  158.  
  159. MotorOn()
  160. {
  161.     /* TURN ON DISK MOTOR ... old motor state is returned in io_Actual */
  162.     diskreq -> iotd_Req.io_Length = 1;
  163.     /* this says motor is to be turned on */
  164.     diskreq -> iotd_Req.io_Command = TD_MOTOR;
  165.     /* do something with the motor */
  166.     DoIO (diskreq);
  167.     return (0);
  168. }
  169.  
  170. MotorOff()
  171. {
  172.     diskreq -> iotd_Req.io_Length = 0;    
  173.     /* says that motor is to be turned on */
  174.     diskreq -> iotd_Req.io_Command = TD_MOTOR;    
  175.     /* do something with the motor */
  176.     DoIO (diskreq);
  177.     return (0);
  178. }
  179.  
  180.  
  181. /*
  182.  * The following code segment was thrown at the USENET by Neil Katin.
  183.  * Thanks, Neil.
  184.  */
  185.  
  186. hash (str)
  187. unsigned char *str;
  188. {
  189.     int res;
  190.     unsigned char *sp;
  191.     unsigned c;
  192.  
  193.     res = strlen (str);
  194.  
  195.     for (sp = str; *sp; sp++) {
  196.         c = *sp;
  197.         if (c >= 'a' && c <= 'z')
  198.             c = c - 'a' + 'A';
  199.         res = ((res * 13 + c) & 0x7ff);
  200.     }
  201.     return (res % 72 + DIR_HASHTAB);
  202. }
  203.